﻿#ifndef _C_IRRLICHT_WIDGET_H_INCLUDE_
#define _C_IRRLICHT_WIDGET_H_INCLUDE_

#include <QMainWindow>
#include <QFrame>
#include <QTimer>
#include <QMenu>

#include "../common/common.h"

#ifdef ENABLE_IRRLICHT

#include "../../extends/irrlicht/include/irrlicht.h"

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

/**
 * @brief The CIrrlichtWidget class 集成irrlicht图像引擎，用于处理一些简单的3d应用，
 *        当前irrlicht 版本由vs2017编译，而且只编译了release版本，如果遇到问题，请irrlicht
 *        官网下载最新版本自行编译,
 *        注意点：这个控件接收消息存在一个问题，测试中发现当鼠标不停在界面上点击拉动的时候，会出现
 *        主界面卡死的情况，无法得知是哪里的问题。
 *        现在的做法是当检测到鼠标事件在控件之外的时候，就显示一个隐藏的菜单，菜单显示会重新让主窗口
 *        能够获取到鼠标事件，
 */
class CIrrlichtWidget : public QFrame
{
    Q_OBJECT

public:
    explicit CIrrlichtWidget(QWidget *parent = nullptr);
    ~CIrrlichtWidget();

    /// 开始工作
    void start(int msec=12);
    /// 判断指定的坐标是否在当前控件内
    bool IsInsidePoint(QMouseEvent *event);
    /// 将屏幕坐标转换为当前控件内坐标
    QPoint ChangeScreenToLocalPos(QMouseEvent *event);

    /// 资源导入
    virtual bool loadResources(void);
    /// 场景渲染
    virtual void render(void);
    /// 处理鼠标事件
    virtual bool onProcessMouseEvent(QMouseEvent *event);
    /// 处理鼠标滚轮事件
    virtual void onProcessWheelEvent(QWheelEvent *event);

protected:
    bool eventFilter(QObject *watched, QEvent *event);

private:
    void IrrMouseEvent(QMouseEvent *e,EMOUSE_INPUT_EVENT eventtype);
    void onProcessResizeEvent(QResizeEvent *event);
    QMainWindow* getMainWindow(void);

protected:
    void timerEvent(QTimerEvent *e) override;

protected:
    QBasicTimer m_rendertimer;
    irr::IrrlichtDevice* m_device;
    IVideoDriver* m_driver;
    ISceneManager* m_smgr;
    IGUIEnvironment* m_guienv;
    bool m_isMouseInside;
    QMenu m_hideMenu;         /**< 用于处理疯狂点击后，可能主窗口无法接收消息的情况 */
};

#endif

#endif // MAINWINDOW_H
